//
//  QuotationList.h
//  Chart
//
//  Created by CaoJun on 13-6-6.
//
//

#ifndef __Chart__QuotationList__
#define __Chart__QuotationList__

#include "Quotation.h"

#include <utility>
#include <vector>
#include <map>

namespace ytx
{
    template<typename T>
    class QuotationList : public std::vector<T*>
    {
    private:
        std::map<std::string, int> quotationMap;
    public:
        QuotationList();
        virtual ~QuotationList();
        virtual void set(T * quotation);
        
        virtual T * get(int index);
        
        virtual T * get(std::string id, LineType::LineType quotationType);

        virtual void on(std::string name, Observer<T> * observer);
        virtual void off(std::string name, Observer<T> * observer);

    };
    
    template<typename T>
    QuotationList<T> :: QuotationList()
    {
        
    }
    
    template<typename T>
    QuotationList<T>::~QuotationList()
    {
        for (auto it = this->begin(); it != this->end(); ++it) {
            delete *it;
            *it = NULL;
        }
    }
    
    template<typename T>
    void QuotationList<T>::set(T *quotation)
    {
        std::string id = quotation->getId();
        std::string type = ConvertToString(quotation->getQuotationType());
        std::string key = id + "_" + type;

        if (quotationMap.find(key) != quotationMap.end()){
            for (auto it = this->begin(); it != this->end();++it) {
                T *q = *it;
                bool date = q->currentDate != quotation->currentDate;
                bool name = typeid(q).name() == typeid(quotation).name();
                bool id_e = q->getId() == id;
                bool type = q->getQuotationType() == quotation->quotationType;
                if (date && name && id_e && type) {
                    this->erase(it);
                    quotationMap.insert(std::pair<std::string, int>(key, (int)(this->size())));
                    this->push_back(quotation);
                    return;
                }
            }
        } else {
            quotationMap.insert(std::pair<std::string, int>(key, (int)(this->size())));
            this->push_back(quotation);
        }
    }
    
    template<typename T>
    T * QuotationList<T>::get(int index)
    {
        return this->operator[](index);
    }
    
    
    template<typename T>
    T * QuotationList<T>::get(std::string id, LineType::LineType QuotationType)
    {
        std::string key = id + "_" + ConvertToString(QuotationType);
        std::map<std::string, int>::iterator it = quotationMap.find(key);
        if (it != quotationMap.end()) {
            return  get(it->second);
        } else {
            return NULL;
        }
    }
    
    template<typename T>
    void QuotationList<T>::on(std::string name, Observer<T> * observer)
    {
        for (auto it = this->begin(); it != this->end();++it) {
            if (!(*it)) {
                continue;
            }
            (*it)->on(name, observer);
        }
    }
    
    template<typename T>
    void QuotationList<T>::off(std::string name, Observer<T> * observer)
    {
        for (auto it = this->begin(); it != this->end();++it) {
            if (!(*it)) {
                continue;
            }
            (*it)->off(name, observer);
        }
    }
}

#endif /* defined(__Chart__QuotationList__) */
